#pragma once

#include <iostream>
#include <string>
#include <functional>
#include <unistd.h>
#include "InetAddr.hpp"
#define LISTENLOCKET 0
#define NORMALSOCKET 1

/*  This is a class that encapsulates sockfd and provides
    an interface that registers callback methods
    to handle the corresponding events
*/
class Reactor;
class Connection;
using handle_t = std::function<void(Connection *con)>;

class Connection
{
public:
    Connection(int sockfd) : _sockfd(sockfd)
    {
    }
    // 注册回调方法来处理已就绪事件
    void RegisEventCallback(handle_t recver, handle_t sender, handle_t error)
    {
        _recv_handle = recver;
        _send_handle = sender;
        _error_handle = error;
    }
    // 构建事件
    void SetEvents(uint32_t events)
    {
        _events = events;
    }
    uint32_t Eevents()
    {
        return _events;
    }
    int SockFd()
    {
        return _sockfd;
    }
    int ConnectionType()
    {
        return _type;
    }
    void SetReactorPtr(Reactor *R)
    {
        _R = R;
    }
    void SetConnectionType(int type)
    {
        _type = type;
    }
    void SetInetAddr(const InetAddr &addr)
    {
        _addr = addr;
    }
    void AppendRecvBuffer(const std::string &in)
    {
        _recv_buffer += in;
    }
    void AppendSendBuffer(const std::string &out)
    {
        _send_buffer += out;
    }
    std::string &SendBuffer()
    {
        return _send_buffer;
    }
    std::string &RecvBuffer()
    {
        return _recv_buffer;
    }
    void ClearBuffer(int n)
    {
        _send_buffer.erase(0, n);
    }
    void Close()
    {
        if (_sockfd > 0)
        {
            ::close(_sockfd);
        }
    }
    ~Connection()
    {
    }

private:
    int _sockfd;              // sockfd
    uint32_t _events;         // fd Concerned Events
    std::string _recv_buffer; // fd对应的接收缓冲区
    std::string _send_buffer; // fd对应的发送缓冲区
    int _type;                // 套接字的类型
    InetAddr _addr;           // 当前Connection的ip + port;
    // 回调处理事件
public:
    handle_t _recv_handle;  // handler read event
    handle_t _send_handle;  // handler write event
    handle_t _error_handle; // handler error event

public:
    Reactor *_R; // 声明自己指向的是那个Reactor对象!
};
